/**
   glut_display.h - Created by Timothy Morey on 8/9/11.

   This file contains defines routines used to display simple raster images,
   and animations thereof, using glut.
 */

#ifndef __GLUT_DISPLAY_H
#define __GLUT_DISPLAY_H

#include <pthread.h>
#include <string>

#include "communication_queue.h"
#include "simulator.h"

/**
   Describes a glut window managed by the system.
 */
struct GlutWindow
{
  int X, Y, Width, Height;
  std::string Name;
  int WindowID;
};

/**
   The GlutDisplay is a singleton object that provides an entry-point into the
   glut display system.
*/
class GlutDisplay
{
public:

  static GlutDisplay& Instance();
  static bool IsInitialized() { return _Instance; }
  static void DestroyInstance();


public:

  void Init(int x, int y, int width, int height, const std::string& name);
  const GlutWindow& GetMainWindow() const { return _MainWindow; }

  void UpdateScreenBounds();

  double GetAverageFrameTime() const { return _AverageTime; }
  void PrintFrameRateReport() const;

protected:

  /**
     Entry-point for the glut window thread.  This function will initialize glut,
     show a window, hookup callbacks, and start the main lopp.

     @param arg A pointer to the GlutWindow that will be created and show by this
     function.
     
     @return Undefined.
  */
  static void* StartGlutLoop(void* arg);

  static void DisplayFunc();
  static void IdleFunc();
  static void KeyboardFunc(unsigned char key, int x, int y);
  static void ReshapeFunc(int width, int height);

  void DrawParticle(double x, double y, double v, const Parameters& parms);
  void DrawCircle(double x, double y, double r, double v);

  void ToggleFullScreenMode();
  void ToggleSimpleRendering();

protected:

  GlutWindow _MainWindow;
  pthread_t _ThreadID;

  CommunicationQueue _Queue;
  bool _FullScreenMode;
  bool _SimpleRendering;

  int _TimeCounts;
  double _ElapsedSum;
  double _AverageTime;


protected:

  GlutDisplay();
  ~GlutDisplay();

  static GlutDisplay* _Instance;

};

#endif
